package com.zhang.mailet;

import org.apache.mailet.Mail;
import org.apache.mailet.base.GenericMailet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import java.io.*;

public class HelloMailet extends GenericMailet {

    private static final Logger LOGGER = LoggerFactory.getLogger(HelloMailet.class);

    @Override
    public void service(Mail mail) throws MessagingException {
        LOGGER.info(mail.getName());
        MimeMessage message = mail.getMessage();
//        message.g
        message.setSubject("Hello " + message.getSubject());
        try {
            MimeMultipart content = (MimeMultipart) message.getContent();
            int counts = content.getCount();
            LOGGER.info("counts {}", counts);
            StringBuilder sb = new StringBuilder();
            getMailContent(sb,message);
            boolean isContainAttach =isContainAttach(message);
            LOGGER.info("isContainAttach {}",  isContainAttach);
            saveAttachMent(message);
            /*for (int i = 0; i < counts; i++) {
                getMailContent(sb, content.getBodyPart(i));
                boolean isContainAttach = isContainAttach(content.getBodyPart(i));
                LOGGER.info("{} isContainAttach {}", i, isContainAttach);
                if (isContainAttach) {
                    saveAttachMent(content.getBodyPart(i));
                }
            }*/
            LOGGER.info("content: {}", sb.toString());
        } catch (Exception e) {
            LOGGER.error("", e);
        }
//        message.setText("Hello Mailet");

    }

    public void getMailContent(StringBuilder bodyText, Part part) throws Exception {


        String contentType = part.getContentType();
//获得邮件的MimeType类型
        System.out.println("邮件的MimeType类型:" + contentType);

        int nameIndex = contentType.indexOf("name");

        boolean conName = false;

        if (nameIndex != -1) {
            conName = true;
        }

        System.out.println("邮件内容的类型:　" + contentType);

        if (part.isMimeType("text/plain") && conName == false) {
//text/plain类型
            bodyText.append((String) part.getContent());
        } else if (part.isMimeType("text/html") && conName == false) {
//text/html类型
            bodyText.append((String) part.getContent());
        } else if (part.isMimeType("multipart/*")) {
//multipart/*
            Multipart multipart = (Multipart) part.getContent();
            int counts = multipart.getCount();
            for (int i = 0; i < counts; i++) {
                getMailContent(bodyText, multipart.getBodyPart(i));
            }
        } else if (part.isMimeType("message/rfc822")) {
//message/rfc822
            getMailContent(bodyText, (Part) part.getContent());
        } else {

        }
    }

    public boolean isContainAttach(Part part) throws Exception {
        boolean attachFlag = false;
//StringcontentType=part.getContentType();
        if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            for (int i = 0; i < mp.getCount(); i++) {
                BodyPart mPart = mp.getBodyPart(i);
                String disposition = mPart.getDisposition();
                if ((disposition != null)
                        && ((disposition.equals(Part.ATTACHMENT)) || (disposition
                        .equals(Part.INLINE))))
                    attachFlag = true;
                else if (mPart.isMimeType("multipart/*")) {
                    attachFlag = isContainAttach((Part) mPart);
                } else {
                    String conType = mPart.getContentType();

                    if (conType.toLowerCase().contains("application"))
                        attachFlag = true;
                    if (conType.toLowerCase().contains("name"))
                        attachFlag = true;
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            attachFlag = isContainAttach((Part) part.getContent());
        }else if (part.isMimeType("application/*")) {
            attachFlag = isContainAttach((Part) part.getContent());
        }
        return attachFlag;
    }

    /**
     * 　*　保存附件
     */

    public void saveAttachMent(Part part) throws Exception {
        LOGGER.info("saveAttachMent");
        String fileName = "";
        if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            for (int i = 0; i < mp.getCount(); i++) {
                BodyPart mPart = mp.getBodyPart(i);
                String disposition = mPart.getDisposition();
                LOGGER.info("disposition {}", disposition);
                if ((disposition != null)
                        && ((disposition.equals(Part.ATTACHMENT)) || (disposition
                        .equals(Part.INLINE)))) {
                    fileName = mPart.getFileName();
                    if (fileName.toLowerCase().indexOf("gb2312") != -1) {
                        fileName = MimeUtility.decodeText(fileName);
                    }
                    saveFile(fileName, mPart.getInputStream());
                } else if (mPart.isMimeType("multipart/*")) {
                    saveAttachMent(mPart);
                } else {

                    fileName = mPart.getFileName();
                    if ((fileName != null)
                            && (fileName.toLowerCase().indexOf("GB2312") != -1)) {
                        fileName = MimeUtility.decodeText(fileName);

                    }
                    LOGGER.info("fileName {}", fileName);
                    saveFile(fileName, mPart.getInputStream());
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            saveAttachMent((Part) part.getContent());
        }
    }

    private void saveFile(String fileName, InputStream in) throws Exception {
        String osName = System.getProperty("os.name");
        String storeDir = "/root/tmp";
        String separator = "";
        if (osName == null) {
            osName = "";
        }
        if (osName.toLowerCase().indexOf("win") != -1) {
            separator = "\\";
            if (storeDir == null || storeDir.equals(""))
                storeDir = "c:\\tmp";
        } else {
            separator = "/";
            storeDir = "/tmp";
        }
        File storeFile = new File(storeDir + separator + fileName);
        System.out.println("附件的保存地址:　" + storeFile.toString());
//for(int　i=0;storefile.exists();i++){
//storefile　=　new　File(storedir+separator+fileName+i);
//}
        BufferedOutputStream bos = null;
        BufferedInputStream bis = null;

        try {
            bos = new BufferedOutputStream(new FileOutputStream(storeFile));
            bis = new BufferedInputStream(in);
            int c;
            while ((c = bis.read()) != -1) {
                bos.write(c);
                bos.flush();
            }
        } catch (Exception exception) {
            exception.printStackTrace();
            throw new Exception("文件保存失败!");
        } finally {
            bos.close();
            bis.close();
        }
    }


}
